home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / QBASGDC1.ZIP / QBASGDC1.001 < prev    next >
Text File  |  1994-09-28  |  25KB  |  783 lines

  1. ╓───────────────╖
  2. ║ Week 1, Day 1 ║
  3. ╙───────────────╜
  4.  
  5. Today you will learn how to make a PACMAN symbol move across the screen.
  6.  
  7. Start QBasic and type in the following program:
  8.  
  9. CLS
  10. PRINT "Below is PACMAN himself!"
  11. PRINT "C"
  12.  
  13. Now RUN the program by pressing ALT-R and then S.
  14. Is the graphics a little unconvincing?  Well, we have to start somewhere!
  15.  
  16. The command CLS clears the screen and we'll use it often.
  17.  
  18. Lets put PACMAN in the middle of the screen.
  19. The command you need is LOCATE.
  20. Type (or edit) and RUN the following:
  21.  
  22. CLS
  23. LOCATE 12,40
  24. PRINT "C"
  25.  
  26. Easy as pie!  
  27. The first value between the brackets indicates the row, ranging from 1 at the
  28. top to 23 at the bottom on the screen.
  29. The second value is the column and ranges from 1 at the left to 80 at the right
  30. on the screen.
  31.  
  32. Now to make PACMAN move!
  33. You could do it this way:
  34.  
  35. LOCATE 12,1
  36. PRINT "C"
  37. LOCATE 12,1
  38. PRINT " "        :REM delete the old picture
  39. LOCATE 12,2
  40. PRINT "C"        :REM draw a new picture to the right
  41.  
  42. (REM statements are ignored by the computer and you dont have to type )
  43. (them in.                                                             )
  44. (I will use REM statements to clarify and comment upon my programming.)
  45.  
  46. This method will take forever to program so lets start using variables.
  47.  
  48. A variable is described has a name and contains a value.
  49. This illustrates the difference between a numeric- and a string variable:
  50.  
  51. contents ───->   │ 10 │   │ "twenty" │
  52.                  └────┘   └──────────┘
  53.     name ───->   apples      pears$
  54.                 (numeric)   (string)
  55.  
  56. The "$" in "pears$" is pronounced "string" and identifies it as a string
  57. variable.
  58. When you PRINT a variable its contents is shown, not its name.
  59. Type (or edit) and RUN:
  60.  
  61. CLS
  62. apples = 10
  63. pears$ = "twenty"
  64. PRINT "Amount of apples are "; apples
  65. PRINT "Amount of pears are "; pears$
  66.  
  67. Notice how the text between the double quotes is displayed literally while
  68. the variable name is replaced by its contents.
  69. The "=" operator assigns a value to a variable and does it by working from 
  70. right to left, e.g. in "apples = 10" the "10" goes into "apples".
  71. The ";" causes the computer to remember where it last PRINTed and the following
  72. PRINT will continue at that position.
  73. PRINT "ABC" will give the same output as PRINT "A"; "B"; "C"
  74.  
  75. While PACMAN is warming up for his jog, lets make things even easier on
  76. ourselves.
  77. You might have figured that I want to use variables in the following way:
  78.  
  79. column = 1
  80. LOCATE 12,column          :REM This translates to LOCATE 12,1
  81. PRINT "C"
  82. column = column + 1       :REM Lets calculate the value:
  83.                           :REM column + 1 gives you 1 + 1, in other words 2
  84. LOCATE 12,column          :REM This translates to LOCATE 12,2
  85. PRINT "C"
  86.  
  87. Still lots of repetition!
  88. An easier way is to make the computer go in a "loop", increasing the value of
  89. "column" and printing PACMAN.
  90. Type (or edit) and RUN:
  91.  
  92. CLS
  93. FOR column = 1 TO 80
  94. LOCATE 12,column
  95. PRINT "C"
  96. NEXT column
  97.  
  98. Hope I haven't put you off programming altogether with that one!
  99. You've implemented as so-called "FOR..NEXT loop" and here's the low-down on it:
  100. The "FOR" line tells the computer that a variable called column will start off
  101. at 1 and then increase in value until it reaches 80.
  102. The "NEXT" line increases column's value with one and makes the program jump
  103. back to the "LOCATE" line. 
  104. Everything between the "FOR" and the "NEXT" is thus the actual loop and gets
  105. repeated 80 times.
  106.  
  107. If you still dont understand the concept of the "FOR..NEXT loop" then type and
  108. RUN:
  109.  
  110. CLS
  111. FOR values = 1 TO 10
  112. PRINT values
  113. NEXT values
  114.  
  115. Hope you've found the experience enlightening!
  116.  
  117. Clearly also is that everything is happening too fast.
  118. PACMAN completes his trip in the blink of an eye or, depending on how fast
  119. your computer is, even less!
  120. The solution is to use the SLEEP command which waits a number of seconds.
  121. Type (or edit) and RUN:
  122.  
  123. CLS
  124. FOR column = 1 TO 80
  125. LOCATE 12,column
  126. PRINT "C"
  127. SLEEP 1
  128. NEXT column
  129.  
  130. Too slow now!
  131. Another way is to use an empty FOR..NEXT loop that does nothing but kill time.
  132. That way you can change the value of the loop untill it provides an acceptable
  133. delay for your computer.  
  134.  
  135. Another problem was that the PACMAN isn't deleted in its old position and you 
  136. are left with a whole row of "CCCCCC"s.  We'll solve that now.
  137. Here's the final code for the PACMAN 100m sprint:
  138. Type (or edit) and RUN!
  139.  
  140. CLS
  141. FOR column = 1 TO 79
  142. LOCATE 12,column
  143. PRINT " C"
  144. FOR nothing = 1 TO 100          :REM  <─┬─ This just delays the computer
  145. NEXT nothing                    :REM   ─┘
  146. NEXT column
  147.  
  148. If you didnt see a thing the program is probably still too fast for your
  149. computer, so try changing the limit of the "nothing" loop to 300 or more.
  150.  
  151. The space before PACMAN cleverly deletes its old position.
  152. How?  Two characters are displayed (a " " and a "C") but the position only
  153. shift one to the right.
  154. When the two characters are displayed at their new position, the " " overlaps
  155. with the "C" previously displayed and effectively deletes it.
  156. That's all for today!
  157.  
  158. -------------------------------------------------------------------------------
  159. ╓───────────────╖
  160. ║ Week 1, Day 2 ║
  161. ╙───────────────╜
  162.  
  163. Watching PACMAN move is fun, but being in control opens up endless 
  164. possibilities..
  165. Enough said!   
  166. Remember the FOR..NEXT loop?
  167. Lets have a look at a different kind of loop.
  168. Type (or edit) and RUN:
  169.  
  170. CLS                             
  171. value = 1                  
  172. DO WHILE value < 11
  173.  PRINT value                     :REM  <─┬─ This is the loop
  174.  value = value + 1               :REM   ─┘
  175. LOOP
  176.  
  177. This displayed numbers 1 through 10.
  178. The program loops while "value" is less than 11.
  179. We will now use the DO..WHILE loop to read the keyboard and display the 
  180. characters that you press. 
  181. However, there's one snag.  The program will loop "forever" unless you stop it!
  182. Pressing CTL and BREAK at the same time will do this. 
  183. Type (or edit) and RUN:
  184.  
  185. CLS
  186. DO                                  :REM there's no WHILE, so DO forever..
  187.  keyed$ = INKEY$                    :REM make keyed$ = the key pressed
  188.  IF keyed$ <> "" THEN PRINT keyed$  :REM if keyed$ isnt empty then display it
  189. LOOP
  190.  
  191. I bet INKEY$ has you confused!
  192. INKEY$ is a special string variable.
  193. The computer always sets the value of INKEY$ to the key that you press.
  194. While you're not pressing any keys it will contain nothing (nothing is "").
  195. The IF command is very straight forward.
  196. IF something is true THEN do something..  got it?
  197. So IF keyed$ is not equal to nothing THEN its value gets PRINTed.
  198. If I didnt include the IF clause then keyed$ would always be PRINTed, whether 
  199. it contained a value or not.
  200. Try leaving out the IF..THEN part and you'll see what I mean!
  201. Lots and lots of "nothings" fill the screen!
  202.  
  203. Armed with our new commands we can finally control PACMAN with the keyboard.
  204. Type (or edit) and RUN:
  205.  
  206. CLS
  207. row = 12
  208. column = 40
  209. DO 
  210.  DO                           :REM <─┐ this loop waits for a key to be pressed
  211.   keyed$ = INKEY$             :REM   │
  212.  LOOP UNTIL keyed$ <> ""      :REM  ─┘
  213.  LOCATE row, column
  214.  PRINT " "                               :REM this erases the "C"       
  215.  IF keyed$ = "q" THEN row = row - 1       
  216.  IF keyed$ = "a" THEN row = row + 1
  217.  IF keyed$ = "o" THEN column = column - 1
  218.  IF keyed$ = "p" THEN column = column + 1
  219.  LOCATE row, column
  220.  PRINT "C"                              :REM shows the "C" at the new position 
  221. LOOP
  222.  
  223. Note that you can use your own choice of keys by replacing "q","a","o" and "p".
  224. Using special keys like the cursor keys is another cup of tea.
  225.  
  226. If you move PACMAN outside the screen boundaries you'll get an error message.
  227. To prevent this you must add checks to the program.
  228. Just replace the IFs with the following lines and RUN:
  229.  
  230. IF (keyed$ = "q") AND (row > 1) THEN row = row - 1
  231. IF (keyed$ = "a") AND (row < 23) THEN row = row + 1
  232. IF (keyed$ = "o") AND (column > 1) THEN column = column - 1
  233. IF (keyed$ = "p") AND (column < 80) THEN column = column + 1
  234.  
  235. This should do for today.
  236. Hope you enjoyed this as much as I did!
  237.  
  238. -------------------------------------------------------------------------------
  239. ╓───────────────╖
  240. ║ Week 1, Day 3 ║
  241. ╙───────────────╜
  242.  
  243. A playing area is essential to any game so lets design a maze for our PACMAN.
  244.  
  245. First I'll have to tell you about arrays.
  246. Take a look at this example:
  247.  
  248. DIM values(3)
  249. values(1) = 5
  250. values(2) = 92
  251. values(3) = 45
  252.  
  253. Arrays are variables containing multiple elements.
  254. Each element is named after the array followed by a number to specify the 
  255. position of the element.
  256. Each element has its own value.
  257. Type (or edit) and RUN the following to see how arrays can save you from a lot
  258. of repetitive programming:
  259.  
  260. CLS
  261. DIM values(10)
  262. FOR count = 1 TO 10
  263.  values(count) = count
  264. NEXT count
  265. FOR count = 1 to 10
  266.  PRINT values(count)  
  267. NEXT count
  268.   
  269. Remember that "count" ranges from 1 to 10 so the line "values(count) = count"
  270. translates to "values(1) = 1, values(2) = 2, values(3) = 3" etc.  
  271.  
  272. Now lets define our maze. Type (or edit) and RUN:
  273.  
  274. CLS
  275. DIM maze$(6)
  276. maze$(1) = "#########"
  277. maze$(2) = "#   #   #"
  278. maze$(3) = "# # # # #"
  279. maze$(4) = "# #   # #"
  280. maze$(5) = "#   #   #"
  281. maze$(6) = "#########"
  282. FOR count = 1 to 6
  283.  PRINT maze$(count)
  284. NEXT count
  285.  
  286. Now lets put PACMAN in the maze.
  287. Wait - there's nothing that will keep him from moving over the walls.
  288. To solve that problem I'll show you how to inspect the maze (the contents of
  289. maze$).
  290.  
  291. The command MID$ allows you to look at parts of a string variable.
  292. It has the following format: MID$(name of string, starting position, number of
  293. letters). 
  294. Lets look at an example:
  295. alphabet$ = "ABCDE"
  296. PRINT MID$(alphabet$, 1, 2)         :REM displays "AB"
  297. PRINT MID$(alphabet$, 3, 1)         :REM displays "C"
  298.  
  299. Every time PACMAN moves we'll use his position (row and column) to see if he
  300. overlaps a wall in the maze.
  301. Type (or edit) and RUN: (you'll have to press CTRL-BREAK to stop the program)
  302.  
  303. CLS
  304. DIM maze$(6)
  305. maze$(1) = "#########"
  306. maze$(2) = "#   #   #"
  307. maze$(3) = "# # # # #"
  308. maze$(4) = "# #   # #"
  309. maze$(5) = "#   #   #"
  310. maze$(6) = "#########"
  311. row = 5
  312. column = 3
  313. DO
  314.  LOCATE 1, 1
  315.  FOR count = 1 to 6
  316.   PRINT maze$(count)                  :REM PRINT the maze
  317.  NEXT count 
  318.  LOCATE row, column
  319.  PRINT "C"                            :REM PRINT PACMAN
  320.  DO
  321.   keyed$ = INKEY$
  322.  LOOP UNTIL keyed$ <> ""
  323.  oldRow = row                         :REM remember old position of PACMAN 
  324.  oldColumn = column
  325.  IF keyed$ = "q" THEN row = row - 1
  326.  IF keyed$ = "a" THEN row = row + 1
  327.  IF keyed$ = "o" THEN column = column - 1
  328.  IF keyed$ = "p" THEN column = column + 1
  329.  IF MID$(maze$(row), column, 1) = "#" THEN
  330.   row = oldRow                                 :REM <─┬ move PACMAN back to his
  331.   column = oldColumn                           :REM  ─┘ old position
  332.  END IF
  333. LOOP 
  334.  
  335. All that needs mentioning is that I used the "IF..END IF" structure to allow
  336. for more than one action.
  337.  
  338. If you type in the examples you can save yourself some time by saving the
  339. PACMAN game to disk (press ALT-F then S), because we will re-use the game
  340. during the rest of the week.
  341.  
  342. Tomorrow we'll add dots and a ghost to the maze!
  343.  
  344. -------------------------------------------------------------------------------
  345. ╓───────────────╖
  346. ║ Week 1, Day 4 ║
  347. ╙───────────────╜
  348.  
  349. Add the dots to the maze by changing the following lines:
  350.  
  351. maze$(1) = "#########"
  352. maze$(2) = "#...#...#"
  353. maze$(3) = "#.#.#.#.#"
  354. maze$(4) = "#.#...#.#"
  355. maze$(5) = "#...#...#"
  356. maze$(6) = "#########"
  357.  
  358. As you might have guessed we'll inspect the maze each time PACMAN moves and
  359. keep count of the number of dots he eat.
  360. A dot has to be removed when eaten. 
  361. When our count reaches 21 (count them!) dots, the game ends.
  362.  
  363. MID$ can be used to change a string variable as well as inspecting it.
  364. Look at the following example:
  365.  
  366. alphabet$="ABCDE"
  367. MID$(alphabet$, 2, 3) = "XYZ"
  368. PRINT alphabet$                    :REM displays "AXYZE"  
  369.  
  370. We'll use MID$ to replace the dots with blanks when PACMAN eats them.
  371. Type (or edit) and RUN: (changes in the program are marked)
  372.  
  373. CLS
  374. DIM maze$(6)
  375. maze$(1) = "#########"
  376. maze$(2) = "#...#...#"
  377. maze$(3) = "#.#.#.#.#"
  378. maze$(4) = "#.#...#.#"
  379. maze$(5) = "#...#...#"
  380. maze$(6) = "#########"
  381. row = 5
  382. column = 3
  383. dots = 21               :REM  <──- new
  384. DO
  385.  LOCATE 1, 1
  386.  FOR count = 1 to 6
  387.   PRINT maze$(count)                 
  388.  NEXT count 
  389.  LOCATE row, column
  390.  PRINT "C"                    
  391.                                                 :REM  <─┬─ new
  392.  IF dots = 0 THEN                                                 
  393.   LOCATE 8, 1                                   :REM    │
  394.   PRINT "You have won!"                         :REM    │
  395.   END                                           :REM    │
  396.  END IF                                         :REM   ─┘
  397.  DO
  398.   keyed$ = INKEY$
  399.  LOOP UNTIL keyed$ <> ""
  400.  oldRow = row                
  401.  oldColumn = column
  402.  IF keyed$ = "q" THEN row = row - 1
  403.  IF keyed$ = "a" THEN row = row + 1
  404.  IF keyed$ = "o" THEN column = column - 1
  405.  IF keyed$ = "p" THEN column = column + 1
  406.  IF MID$(maze$(row), column, 1) = "#" THEN
  407.   row = oldRow         
  408.   column = oldColumn   
  409.  END IF
  410.                                                 :REM  <─┬─ new
  411.  IF MID$(maze$(row), column, 1) = "." THEN   
  412.   MID$(maze$(row), column, 1) = " "             :REM    │
  413.   dots = dots - 1                               :REM    │
  414.  END IF                                         :REM   ─┘
  415. LOOP
  416.  
  417. (QBasic does not allow me to place a ":REM" next to a IF..THEN line. )
  418. (So if you suspect a REM is missing, see if its next tot an IF..THEN.)
  419.  
  420. The reason why we dont do the "IF dots = 0" test directly after inspecting the
  421. maze is because we want to draw PACMAN in his new position before ending the 
  422. game.
  423.  
  424. Here is a better (or clearer) way of inspecting keyed$ and maze$:
  425.  
  426. REM examine the keys
  427. SELECT CASE keyed$
  428.        CASE IS = "q"
  429.         row = row - 1
  430.        CASE IS = "a"
  431.         row = row + 1
  432.        CASE IS = "o"
  433.         column = column - 1
  434.        CASE IS = "p"
  435.         column = column + 1
  436. END SELECT            
  437.  
  438. REM examine the maze 
  439. SELECT CASE MID$(maze$(row), column, 1)
  440.        CASE IS = "#"
  441.         row = oldRow
  442.         column = oldColumn
  443.        CASE IS = "."
  444.         MID$(maze$(row), column, 1) = " "
  445.         dots = dots - 1
  446. END SELECT              
  447.  
  448. SELECT makes it a lot easier to read the program.
  449. Also notice the way I put spaces before (indent) some words.
  450. Another good idea is to use blank lines to seperate the various parts of your
  451. program.
  452.  
  453. Lets place a ghost in the maze.
  454. We'll just display the ghost for now and detect whether PACMAN collides with 
  455. it. Tomorrow we can make it move.
  456.  
  457. Detecting whether there's a collision is a simple matter of comparing PACMAN's
  458. and the ghost's positions (row and column).
  459. Type (or edit) and RUN:
  460.  
  461. CLS
  462.  
  463. DIM maze$(6)
  464. maze$(1) = "#########"
  465. maze$(2) = "#...#...#"
  466. maze$(3) = "#.#.#.#.#"
  467. maze$(4) = "#.#...#.#"
  468. maze$(5) = "#...#...#"
  469. maze$(6) = "#########"
  470.  
  471. row = 5
  472. column = 3
  473. ghostRow = 2                     :REM  <─┬─ new
  474. ghostColumn = 7                  :REM   ─┘
  475. dots = 21                             
  476.  
  477. DO
  478.  
  479.  LOCATE 1, 1
  480.  FOR count = 1 to 6
  481.   PRINT maze$(count)                 
  482.  NEXT count 
  483.  
  484.  LOCATE row, column
  485.  PRINT "C"                    
  486.  
  487.  LOCATE ghostRow, ghostColumn       :REM  <─┬─ new
  488.  PRINT "G"                          :REM   ─┘
  489.  
  490.  IF dots = 0 THEN                                           
  491.   LOCATE 8, 1                                        
  492.   PRINT "You have won!"                               
  493.   END                                               
  494.  END IF                                             
  495.                                                            :REM  <─┬─ new
  496.  IF ((row = ghostRow) AND (column = ghostColumn)) THEN   
  497.   LOCATE 8, 1                                              :REM    │
  498.   PRINT "You've been caught!"                              :REM    │
  499.   END                                                      :REM    │
  500.  END IF                                                    :REM   ─┘
  501.  
  502.  DO
  503.   keyed$ = INKEY$
  504.  LOOP UNTIL keyed$ <> ""
  505.  
  506.  oldRow = row                
  507.  oldColumn = column
  508.  
  509.  REM examine the keys
  510.  SELECT CASE keyed$
  511.        CASE IS = "q"
  512.         row = row - 1
  513.        CASE IS = "a"
  514.         row = row + 1
  515.        CASE IS = "o"
  516.         column = column - 1
  517.        CASE IS = "p"
  518.         column = column + 1
  519.  END SELECT            
  520.  
  521.  REM examine the maze 
  522.  SELECT CASE MID$(maze$(row), column, 1)
  523.        CASE IS = "#"
  524.         row = oldRow
  525.         column = oldColumn
  526.        CASE IS = "."
  527.         MID$(maze$(row), column, 1) = " "
  528.         dots = dots - 1
  529.  END SELECT              
  530.  
  531. LOOP
  532.  
  533. Phew!  I need a rest after that!
  534. Remember to save the program for tomorrow.
  535.  
  536. -------------------------------------------------------------------------------
  537. ╓───────────────╖
  538. ║ Week 1, Day 5 ║
  539. ╙───────────────╜
  540.  
  541. Lets give the ghost some "artificial intelligence".
  542.  
  543. As you might have suspected we will compare his positions with PACMAN's and 
  544. move him one position nearer.
  545. Allowing the ghost to move diagonally will give it an unfair advantage so
  546. ghostRow and ghostColumn will not change at the same time.
  547. Of course the ghost will also have to be blocked by the walls of the maze.
  548. We dont have to check for dots because the ghost dont eat them.
  549.  
  550. So what are we waiting for? Type (or edit) and RUN!
  551.  
  552. CLS
  553.  
  554. DIM maze$(6)
  555. maze$(1) = "#########"
  556. maze$(2) = "#...#...#"
  557. maze$(3) = "#.#.#.#.#"
  558. maze$(4) = "#.#...#.#"
  559. maze$(5) = "#...#...#"
  560. maze$(6) = "#########"
  561.  
  562. row = 5
  563. column = 3 
  564. ghostRow = 2                                   
  565. ghostColumn = 7                      
  566. dots = 21                             
  567.  
  568. DO
  569.  
  570.  LOCATE 1, 1
  571.  FOR count = 1 to 6
  572.   PRINT maze$(count)                 
  573.  NEXT count 
  574.  
  575.  LOCATE row, column
  576.  PRINT "C"                    
  577.  
  578.  LOCATE ghostRow, ghostColumn                    
  579.  PRINT "G"                               
  580.  
  581.  IF dots = 0 THEN                                           
  582.   LOCATE 8, 1                                        
  583.   PRINT "You have won!"                               
  584.   END                                               
  585.  END IF                                             
  586.  
  587.  IF ((row = ghostRow) AND (column = ghostColumn)) THEN                
  588.   LOCATE 8, 1                                                   
  589.   PRINT "You've been caught!"                                   
  590.   END                                                            
  591.  END IF                                                          
  592.  
  593.  DO
  594.   keyed$ = INKEY$
  595.  LOOP UNTIL keyed$ <> ""
  596.  
  597.  oldRow = row                
  598.  oldColumn = column
  599.  
  600.  REM examine the keys
  601.  SELECT CASE keyed$
  602.        CASE IS = "q"
  603.         row = row - 1
  604.        CASE IS = "a"
  605.         row = row + 1
  606.        CASE IS = "o"
  607.         column = column - 1
  608.        CASE IS = "p"
  609.         column = column + 1
  610.  END SELECT            
  611.  
  612.  REM examine the maze 
  613.  SELECT CASE MID$(maze$(row), column, 1)
  614.        CASE IS = "#"
  615.         row = oldRow
  616.         column = oldColumn
  617.        CASE IS = "."
  618.         MID$(maze$(row), column, 1) = " "
  619.         dots = dots - 1
  620.  END SELECT              
  621.  
  622.  REM move ghost closer to PACMAN            :REM <─┐ everything from this point
  623.                                             :REM   │ onwards is new
  624.  oldRow = ghostRow                                            
  625.  SELECT CASE ghostRow 
  626.         CASE < row
  627.          ghostRow = ghostRow + 1
  628.         CASE > row
  629.          ghostRow = ghostRow - 1
  630.  END SELECT
  631.  IF MID$(maze$(ghostRow), ghostColumn, 1) = "#" THEN ghostRow = oldRow
  632.  
  633.  IF ghostRow = oldRow THEN
  634.   oldColumn = ghostColumn
  635.   SELECT CASE ghostColumn
  636.          CASE < column
  637.           ghostColumn = ghostColumn + 1
  638.          CASE > column
  639.           ghostColumn = ghostColumn - 1
  640.   END SELECT            
  641.   IF MID$(maze$(ghostRow), ghostColumn, 1) = "#" THEN ghostColumn = oldColumn
  642.  END IF         
  643. LOOP
  644.  
  645. Notice that I test whether ghostRow has stayed the same ( = oldRow) before
  646. testing for ghostColumn.
  647. This prevents diagonal movement for the ghost.
  648. Another problem is that the ghost waits for you to make a move before moving
  649. himself.
  650. The loop that waits for a key to be pressed is the culprit.
  651. Now we will have to put a delay somewhere in the program because the ghost will
  652. move at blinding speed!
  653. Replace the following lines in the program and RUN it:
  654.  
  655. DO
  656.  keyed$ = INKEY$
  657. LOOP UNTIL keyed$ <> ""
  658.  
  659. with:
  660.  
  661. keyed$ = INKEY$
  662. REM: kill time
  663. FOR nothing = 1 TO 500
  664. NEXT nothing 
  665.  
  666. If the game is still too fast then change the limit of "nothing" to 1000 or 
  667. more.
  668.  
  669. The game is still too difficult because the ghost is too intelligent - it 
  670. follows you at every possible opportunity.
  671. To add some randomness to its pattern we will use the command RND.
  672. The value of RND is never the same (for all practical purposes) but is always
  673. a value between 0 and 1.
  674. The condition "IF RND < 0.1 " is true roughly 10% of the time.
  675. Here is the entire listing with the changes added: (Type (or edit) and RUN)
  676.  
  677. CLS
  678.  
  679. DIM maze$(6)
  680. maze$(1) = "#########"
  681. maze$(2) = "#...#...#"
  682. maze$(3) = "#.#.#.#.#"
  683. maze$(4) = "#.#...#.#"
  684. maze$(5) = "#...#...#"
  685. maze$(6) = "#########"
  686.  
  687. row = 5
  688. column = 3 
  689. ghostRow = 2                                   
  690. ghostColumn = 7                      
  691. dots = 21                             
  692.  
  693. DO
  694.  
  695.  LOCATE 1, 1
  696.  FOR count = 1 to 6
  697.   PRINT maze$(count)                 
  698.  NEXT count 
  699.  
  700.  LOCATE row, column
  701.  PRINT "C"                    
  702.  
  703.  LOCATE ghostRow, ghostColumn                    
  704.  PRINT "G"                               
  705.  
  706.  IF dots = 0 THEN                                           
  707.   LOCATE 8, 1                                        
  708.   PRINT "You have won!"                               
  709.   END                                               
  710.  END IF                                             
  711.  
  712.  IF ((row = ghostRow) AND (column = ghostColumn)) THEN                
  713.   LOCATE 8, 1                                                   
  714.   PRINT "You've been caught!"                                   
  715.   END                                                            
  716.  END IF                                                          
  717.  
  718.  keyed$ = INKEY$
  719.  
  720.  FOR nothing = 1 TO 500                  :REM change if your computer is faster
  721.  NEXT nothing
  722.  
  723.  oldRow = row                
  724.  oldColumn = column
  725.  
  726.  REM examine the keys
  727.  SELECT CASE keyed$
  728.        CASE IS = "q"
  729.         row = row - 1
  730.        CASE IS = "a"
  731.         row = row + 1
  732.        CASE IS = "o"
  733.         column = column - 1
  734.        CASE IS = "p"
  735.         column = column + 1
  736.  END SELECT            
  737.  
  738.  REM examine the maze 
  739.  SELECT CASE MID$(maze$(row), column, 1)
  740.        CASE IS = "#"
  741.         row = oldRow
  742.         column = oldColumn
  743.        CASE IS = "."
  744.         MID$(maze$(row), column, 1) = " "
  745.         dots = dots - 1
  746.  END SELECT              
  747.                                           :REM   <─┬─ new
  748.  IF RND < 0.1 THEN
  749.                                           :REM    ─┘
  750.   REM move ghost closer to PACMAN
  751.   oldRow = ghostRow  
  752.   SELECT CASE ghostRow 
  753.          CASE < row
  754.           ghostRow = ghostRow + 1
  755.          CASE > row
  756.           ghostRow = ghostRow - 1
  757.   END SELECT
  758.   IF MID$(maze$(ghostRow), ghostColumn, 1) = "#" THEN ghostRow = oldRow
  759.  
  760.   IF ghostRow = oldRow THEN
  761.    oldColumn = ghostColumn
  762.    SELECT CASE ghostColumn
  763.           CASE < column
  764.            ghostColumn = ghostColumn + 1
  765.           CASE > column
  766.            ghostColumn = ghostColumn - 1
  767.    END SELECT            
  768.    IF MID$(maze$(ghostRow), ghostColumn, 1) = "#" THEN ghostColumn = oldColumn
  769.   END IF         
  770.  END IF                      :REM  <─── new
  771. LOOP
  772.  
  773. Another way to slow down the game is to use a variable "wait" and add 1 to it
  774. every time the program loops.
  775. Only when "wait" = 20 the ghost is allowed to move.
  776. Remember to reset "wait" to 0 after moving, or its value will be 21, 22, etc.
  777. and never again 20!
  778. If you use this method you must remove the FOR..NEXT loop that kills time.
  779.  
  780. Next week we'll do an RPG!
  781.  
  782. -------------------------------------------------------------------------------
  783.